#include <stdio.h>
#include <linux/limits.h>
#include <string.h>
#include <ctype.h>
#include <vector>
#include <dirent.h>
#include <sys/stat.h>
#include <iostream>
#include <unistd.h>	// fork
#include <sys/types.h>
#include <sys/wait.h> 
#include <vector>
#include <stdlib.h>
#include "WebAndFileinfo.h"
#include "baseInfo.h"	// 基础信息
using namespace std;

typedef struct _WebInfo_
{
    char WebType[PATH_MAX];
	char WebFile[PATH_MAX];
	char WebLog[PATH_MAX];
}WebInfo_, *pWebInfo_;

// 返回src中, 最后一个ch左边的部分 返回值需要外部释放 delete []
char * strleft(char *src, char ch)
{
    int len = strlen(src);
    char *str = new char[len+1];
    memset(str, 0, len+1);

    strcpy(str, src);
	
	char * sub = strrchr(str, ch);
	int n1 = strlen(sub);
	int n2 = strlen(str);
	char *subdir= new char[n2-n1+1];
    memset(subdir, 0, n2-n1+1);
	strncpy(subdir, str, n2-n1);

	return subdir;
}

bool IfDirExist(char *DirPath)
{
    if(DirPath == NULL)
        return false;
    if(opendir(DirPath) == NULL)
        return false;
    
    return true;
}

// 将字符串变小写
char *strToLowr(char *src)
{
    char *temp = src;
	for(; *src != '\0'; src++)
	{
		*src = tolower(*src);
	}

	return temp;
}

// 将字符串变大写
char *strToUpr(char *src)
{
    char *temp = src;
	for(; *src != '\0'; src++)
	{
		*src = toupper(*src);
	}

	return temp;
}

void FindWebDir(char *Path, vector<pWebInfo_>&vt, sqlite3 *db, char *eventId,char *Mac)
{
    DIR 	*pDir;  
	struct 	dirent *ent;
    struct stat statbuf;

	char *dbname = "./hongtan004_linux.db";
    char *cPath = Path; 

	vector<pair<unsigned int, char*> >vtr;
	vector<pair<unsigned int, char*> >::iterator itr;

    //printf("CPath======:%s\n", cPath);
    pDir=opendir(Path);
    //cout<<"aaa"<<endl;

	if(pDir == NULL)
		return;
	while((ent=readdir(pDir))!=NULL) 
	{
		//cout <<"bbb"<<endl;
		//lstat(ent->d_name,&statbuf);
		if(ent->d_type == DT_DIR)  
		{
			char *cName = ent->d_name;
			char * DirName = cName;
			//char *DirName = strToLowr(cName);
			if(strcmp(DirName,".")==0 || strcmp(DirName,"..")==0)  
				continue; 
			
			//printf("Dir=%s\n", ent->d_name);
			
			if(strcmp(DirName, "bin") == 0)
			{
				int nIsMiddleWare = 0;

				char tempPath[PATH_MAX] = {0};
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/conf", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/lib", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/logs", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/temp", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/webapps", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/work", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				if(6 == nIsMiddleWare)	// 是tomcat
				{
					pWebInfo_ pWebInfo = new WebInfo_;
					memset(pWebInfo, 0, sizeof(WebInfo_));
					strcpy(pWebInfo->WebType, "Tomcat");

					strcpy(pWebInfo->WebFile, cPath);
					sprintf(pWebInfo->WebLog, "%s/logs", cPath);
					vt.push_back(pWebInfo);
				}
				
				nIsMiddleWare = 0;
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/cgi-bin", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/conf", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/logs", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/modules", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				if(4 == nIsMiddleWare) // apache
				{
					pWebInfo_ pWebInfo = new WebInfo_;
					memset(pWebInfo, 0, sizeof(WebInfo_));
					strcpy(pWebInfo->WebType, "Apache");
					strcpy(pWebInfo->WebFile, cPath);

					sprintf(pWebInfo->WebLog, "%s/logs", cPath);
					vt.push_back(pWebInfo);
				}

				nIsMiddleWare = 0;
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/client", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/docs", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/lib", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/server", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				if(4 == nIsMiddleWare)	// Jboss
				{
					pWebInfo_ pWebInfo = new WebInfo_;
					memset(pWebInfo, 0, sizeof(WebInfo_));
					strcpy(pWebInfo->WebType, "Jboss");
					strcpy(pWebInfo->WebFile, cPath);

					sprintf(pWebInfo->WebLog, "%s/server/default/log", cPath);
					vt.push_back(pWebInfo);
				}

				nIsMiddleWare = 0;
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/coherence", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/jdk", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/jrockit", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/logs", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/modules", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/user_projects", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/utils", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/wlserver", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				if(8 == nIsMiddleWare)	// weblogic
				{
					pWebInfo_ pWebInfo = new WebInfo_;
					memset(pWebInfo, 0, sizeof(WebInfo_));
					strcpy(pWebInfo->WebType, "Weblogic");

					char temp[PATH_MAX] = {0};
					memset(temp, 0, sizeof(char)*PATH_MAX);
					//cout << "cPath="<<cPath<<endl;
					sprintf(temp, "%s/user_projects/domains", cPath);

					DIR *pDir1;
					struct dirent * dent;
					pDir1 = opendir(temp);
					if(pDir1 != NULL)
					{
						while((dent=readdir(pDir1)) != NULL)
						{
							if(dent->d_type == DT_DIR)
							{
								if(strcmp(dent->d_name,".")==0 || strcmp(dent->d_name,"..")==0)  
									continue; 

								char temp2[PATH_MAX] = {0};
								memset(temp2, 0, sizeof(char)*PATH_MAX);
								sprintf(temp2, "%s/user_projects/domains/%s/servers/AdminServer/logs", cPath, dent->d_name);
cout<<"temp2="<<temp2<<endl;
								//if(opendir(temp2) != NULL)
								if(IfDirExist(temp2))
								{
									strcpy(pWebInfo->WebLog, temp2);

									//char temp3[PATH_MAX] = {0};
									//memset(temp3, 0, sizeof(char)*PATH_MAX);
									//sprintf(temp3, "%s/user_projects/domains/%s", cPath, dent->d_name);

									strcpy(pWebInfo->WebFile, cPath);
									vt.push_back(pWebInfo);
								}
							}
						}
					}
				}



			}
			

			char temp4[PATH_MAX] = {0};
			
			memset(temp4, 0, sizeof(char)*PATH_MAX);
			if(strcmp(cPath, "/") == 0)
				sprintf(temp4, "/%s", ent->d_name);
			else
				sprintf(temp4, "%s/%s", cPath,ent->d_name);
		
			FindWebDir(temp4, vt, db, eventId,Mac);

		}
		else
		{
			char * DirName = ent->d_name;
			char filePath[PATH_MAX] = {0};
			sprintf(filePath, "%s/%s", Path, DirName);
			
			
			// 暂时屏蔽
			/*if(strstr(filePath,"usr/lib")||strstr(filePath,"/lib")||strstr(filePath,"/lib64")||strstr(filePath,"/opt")||strstr(filePath,"/etc")||strstr(filePath,"/home"))
			{
				//cout << "filename=" << filePath << endl;
				GetFileInfo(filePath, db, vtr, eventId,Mac);
			}
			*/

			if(strcmp(DirName, "nginx.exe") == 0)
			{
				//cout << "Name="<<DirName<<endl;
				//cout << "CPath"<<cPath<<endl;
				int nIsMiddleWare = 0;
				
				char tempPath[PATH_MAX] = {0};
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/conf", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/contrib", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/html", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/docs", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/logs", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				memset(tempPath, 0, sizeof(char)*PATH_MAX);
				sprintf(tempPath, "%s/temp", cPath);
				if(IfDirExist(tempPath))
				{
					nIsMiddleWare++;
				}
				//cout <<nIsMiddleWare<<endl;
				if(6 == nIsMiddleWare)	//nginx
				{
					//cout << "nginx" <<endl;
					pWebInfo_ pWebInfo = new WebInfo_;
					memset(pWebInfo, 0, sizeof(WebInfo_));
					strcpy(pWebInfo->WebType, "Nginx");
					strcpy(pWebInfo->WebFile, cPath);

					sprintf(pWebInfo->WebLog, "%s/logs", cPath);
					vt.push_back(pWebInfo);
				}
			}
		}
	}
	
	for(itr = vtr.begin(); itr != vtr.end(); itr ++)
	{
		if((*itr).second != NULL)
		{
			delete (*itr).second;
			(*itr).second = NULL;
		}
	}

	remove("./uid.temp");
	
    if(pDir != NULL)
        closedir(pDir);
    //printf("end\n");

}
/*
void GetMac(char *cMac)
{
    int fd;
    int interfaceNum = 0;
    struct ifreq buf[16];
    struct ifconf ifc;
    struct ifreq ifrcopy;
    char mac[18] = {0};
    //char ip[32] = {0};
    //char broadAddr[32] = {0};
    //char subnetMask[32] = {0};


    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("socket");
        close(fd);
        return ;
    }

    ifc.ifc_len = sizeof(buf);
    ifc.ifc_buf = (caddr_t)buf;
    if (!ioctl(fd, SIOCGIFCONF, (char *)&ifc))
    {
        interfaceNum = ifc.ifc_len / sizeof(struct ifreq);
        //printf("interface num = %d\n", interfaceNum);
        while (interfaceNum-- > 0)
        {
            //printf("ndevice name: %s\n", buf[interfaceNum].ifr_name);
            ifrcopy = buf[interfaceNum];
            if (ioctl(fd, SIOCGIFFLAGS, &ifrcopy))
            {
                //printf("ioctl: %s [%s:%d]n", strerror(errno), __FILE__, __LINE__);
                close(fd);
                return ;
            }
            //get the mac of this interface  
            if (!ioctl(fd, SIOCGIFHWADDR, (char *)(&buf[interfaceNum])))
            {
                memset(mac, 0, sizeof(mac));
                snprintf(mac, sizeof(mac), "%02x-%02x-%02x-%02x-%02x-%02x",
                    (unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[0],
                    (unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[1],
                    (unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[2],
                    (unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[3],
                    (unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[4],
                    (unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[5]
                );
                char * failMac = "00-00-00-00-00-00";
                //cout << "mac =" << mac << endl;
                if(strcmp(mac, failMac) != 0)
                {
                    //printf("device mac: %s\n", mac);
                    memcpy(cMac, mac, strlen(mac));
                    break;
                }
            }
            else
            {
                //printf("ioctl: %s [%s:%d]n", strerror(errno), __FILE__, __LINE__);
                close(fd);
                return ;
            }

        }
    }

    close(fd);
memset(g_Mac,0,100);
char cIp[36];           // 本地ip
    	memset(cIp, 0, sizeof(cIp));
    	LocalIp(cIp, 36);
 	//char Mac[100];
	//memset(Mac,0,sizeof(Mac));
	strcat(g_Mac,mac);
	strcat(g_Mac,"~~");
	strcat(g_Mac,cIp);
}*/
// WebType: 中间件类型， Pc_Account表需要
int WebAndFileinfo(sqlite3 *db, char *eventId, char *cWebType, char *rstPath,char *Mac)
{
    vector<pWebInfo_> vtWeb;
cout<<Mac<<endl;
    //strcpy(g_Mac,Mac);
//cout<<g_Mac<<endl;
    char *path = "/";	// 搜索中间件的起始目录
	char *ToolName1 = "./watcherscan-i386.bin";
	char *ToolName2 = "./watchertrack-i386.bin";
    
	// 先删除之前的Web采集结果
	//system("rm ./ThreatDetectionSystem/result/*.zip");

    //char *path = const_cast< char* >(argv[1]);
    if(path == NULL)
        return -1;
#if 0
	pWebInfo_ pinf = new WebInfo_;
	strcpy(pinf->WebFile, "/home/yundun/Apache");
	strcpy(pinf->WebLog, "/home/yundun/Apache/logs");
	strcpy(pinf->WebType, "apache");
	vtWeb.push_back(pinf);

	pWebInfo_ pinf2 = new WebInfo_;
	strcpy(pinf2->WebFile, "/home/opt//apache-tomcat-7.0.78");
	strcpy(pinf2->WebLog, "/home/opt//apache-tomcat-7.0.78/logs");
	strcpy(pinf2->WebType, "tomcat");
	vtWeb.push_back(pinf2);
#else		
    FindWebDir(path, vtWeb, db, eventId,Mac);
#endif
    vector<pWebInfo_>::iterator it;
	char arg[PATH_MAX*2] = {0};
	int i = 1;
    for(it = vtWeb.begin(); it != vtWeb.end(); it++)
    {
        if(*it == NULL)
            continue;
		char subPath[256];
		char logspath[256];
		char cmd[256];
		char dircmd[256];
		while(true)
		{
			memset(subPath, 0, sizeof(subPath));
			memset(logspath, 0, sizeof(logspath));
			memset(cmd, 0, sizeof(cmd));
			//snprintf(subPath, 255, "%s/WebAttackAction/result%d", rstPath, i);
			snprintf(subPath, 255, "/%s/result%d", rstPath, i);
			snprintf(logspath, 255, "%s/%s", subPath, "logs");
			snprintf(cmd, 255, "cp -r %s %s", (*it)->WebLog,logspath);
			snprintf(dircmd, 255, "mkdir %s", logspath);
			
			//mkdir(logspath, 777);
			
			cout<<"logs="<<logspath<<endl;
			cout<<"cmd="<<cmd<<endl;
			cout<<"dircmd="<<dircmd<<endl;
			memset(logspath, 0, sizeof(logspath));
			if(access(subPath, R_OK))
			{
				// 创建一个新目录存放结果
				mkdir(subPath, 0777);
				memset(subPath, 0, sizeof(subPath));
				//system(dircmd);
				system(cmd);
				// 创建完路径后，加上../../再传给Web工具， 因为Web工具运行前调用chdir切换了工作目录.
				//snprintf(subPath, 255, "../../%s/WebAttackAction/result%d", rstPath, i);
				snprintf(subPath, 255, "/%s/result%d", rstPath, i);
				//cout << subPath << endl;
				break;
			}
			else // 目录已存在，
				++i;
		}
		
		
		if(strlen(cWebType) > 0);
			strcat(cWebType, ",");
		strcat(cWebType, (*it)->WebType);
        //cout <<"WebType="<<(*it)->WebType<<endl;
        //cout <<"WebFile="<<(*it)->WebFile<<endl;
        cout <<"WebLog="<<(*it)->WebLog<<endl;

		pid_t Pid;
		Pid = fork();
		if(Pid < 0)
			return -1;
		else if(Pid == 0)	// 子进程
		{
			//文件检测调用规则: 工具名 d -t 0.6 -d 检测路径 -r 规则文件 -o 结果保存路径  （d是运行模式，-t是线程负荷， -r 可以有多个）
			//日志检测调用规则: 工具名 attack -t 中间件类型 -d 日志路径 -o 结果保存路径

			cout << (*it)->WebType << "-File" << endl;

			char *rule1 = "base_rule/yara/apt/apt.yarag";
			char *rule2 = "base_rule/yara/webshell/webshell.yarag";
			char *rule3 = "base_rule/yara/badspeech/badspeech.yarag";
			//char * arg1[] = {"./watcherscan-i386.bin", "d", "-d", (*it)->WebFile, "-r", rule1, "-o", subPath};
			string str;
			str = ToolName1;
			str += " d -d ";
			str += (*it)->WebFile;
			str += " -r ";
			str += rule1;
			str += " -r ";
			str += rule2;
			str += " -r ";
			str += rule3;
			str += " -o ";
			str += subPath;

			cout << (*it)->WebFile << endl;
			
			chdir("./WebEngine/watcherscan/");
			system(str.c_str());
			//execve(ToolName1, arg1, NULL);
			exit(0);
			
		}
		else	// 父进程
		{
			int status;
			waitpid(Pid, &status, 0);

			pid_t pid2;
			pid2 = fork();
			if(pid2 < 0)
				return -2;
			else if(pid2 == 0)// 子进程
			{
				cout << (*it)->WebType << "-Log" << endl;
				string str;
				str = ToolName2;\
				//xjf add --skip=false 
				str += " attack --skip=false -t ";
				str += (*it)->WebType;
				str += " -d ";
				str += (*it)->WebLog;
				str += " -o ";
				str += subPath;
				cout<<str<<endl;
				//char * arg2[] = {"./watchertrack-i386.bin", "attack", "-t", (*it)->WebType, "-d", (*it)->WebLog, "-o", subPath};
				chdir("./WebEngine/watchertrack/");
				system(str.c_str());
				//system("pwd");
				//execve(ToolName2, arg2, NULL);
				
				exit(0);
			}
			else //父进程
			{
				int status2;
				waitpid(pid2, &status2, 0);
			}

			//cout << "父进程"<<status<<endl;
			
			//continue;
		}
		++i;
    }

    return 0;
}
